/**
 * Copyright (c) 2010 Basil Shikin, BugStat Project
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
package org.bugstat.generators;

import java.util.Date;
import java.util.List;

import org.bugstat.common.TimeInterval;
import org.bugstat.common.bugs.Bug;
import org.bugstat.common.reports.Report;

/**
 * This interface defines a class that is able to generate reports form given
 * bug indices. Report generator may generate one or more {@link Report} objects. Note, that multiple reports
 * are used for cases like 'Open bugs per person' reports, where one report is generated for the person.
 * <p>
 * Report generator must be annotated with {@link CanGenerateReports} to be picked up.
 * <p>
 * Report generator is called back when new report data is available. Regular callback flow is as follows:
 * <ol>
 *      <li><code>startedGeneratingReports()</code> Means that we have started generating new report (it is called once
 *                                                  per report generation).
 *                                                  
 *      <li><code>periodStarted()</code> Called when new report date started (it is called every time new
 *                                          week has started).
 *                                           
 *      <li><code>processBug()</code> Called for each bug that exists during the report date (it is called once for each
 *                                    bug per current period. So, if by the end of current week bug tracker had total
 *                                    of 1000 bugs, this function will be called 100 times (once for each bug). If there
 *                                    was 1017 bugs during next week, this function will be called 1017 times (after
 *                                    <code>periodStarted()</code> is called).
 *                                    
 *      <li><code>periodEnded()</code> Called when new report date ended (it is called every time new
 *                                     week has ended).
 *                                     
 *      <li><code>finishedGeneratingReports()</code> Means that no more report data is available (it is called once per
 *                                                  report generation, at the very end).
 *                                                
 *                                                
 *      <li><code>getGeneratedReport()</code> This method is called to get reports that were actually generated.
 * </ol>
 * 
 * @author Basil Shikin
 *
 */
public interface ReportGenerator
{
    /**
     * Get user-friendly name of the generator. This name should answer question: "what report do you generate?".
     * For example, if generator generates number of bugs per person reports, the name should be "Open bugs per person". 
     * 
     * @return User-friendly (and localized) generator name.
     */
    public String getName();
    
    /**
     * Get a priority of this set of reports. The higher the number, the higher on
     * the list of generated reports this one should appear
     * 
     * @return Sort priority
     */
    public int getSortPriority();
    
    /**
     * This method is called when new set reports are about to be generated. It is 
     * called once per generation.
     * 
     * @param timeInterval Interval for which reports will be generated
     * @param context   Current generation context (used to access shared information).
     */
    public void startedGeneratingReports( TimeInterval timeInterval, ReportGeneratorContext context );
    
    /**
     * This method is called once per time step. It means that all calls about bugs will belong
     * to specified period.
     * 
     * @param endDate Period end date. Period start date is previously called end date plus time step.
     */
    public void periodStarted( final Date endDate );
    
    /**
     * This method is called once per bug per time step.
     * 
     * @param bug   Bug to process. It contains state as of current time step.
     */
    public void processBug( final Bug bug );
    
    /**
     * This method is called once per time step. It means that no more bugs will be belong to
     * specified period.
     */
    public void periodEnded();
    
    /**
     * This method is called when no more periods are left and there will no more bugs reported.
     */
    public void finishedGeneratingReports();
    
    
    /**
     * This method is called to retrieve all generated reports.
     * 
     * @return All reports generated for the period.
     */
    public List<Report> getGeneratedReports();
}  
